package company;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.util.regex.Pattern;

import org.apache.commons.fileupload.*;

import javax.xml.parsers.*;
import org.w3c.dom.*;

import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class ConnectorServlet extends HttpServlet {

	private static String baseDir;

	private static boolean debug = false;

	// 允许上传的Image类型的文件类�?

	private static String allowedType;

	// 不允许上传的File类型的文件类�?

	private static String unallowedFileType;

	/**
	 * 初始�? servlet. <br>
	 * Retrieve from the servlet configuration the "baseDir" which is the root
	 * of the file repository: <br>
	 * If not specified the value of "/UserFiles/" will be used.
	 * 
	 */
	public void init() throws ServletException {
		baseDir = getInitParameter("baseDir");
		debug = (new Boolean(getInitParameter("debug"))).booleanValue();
		// 设置baseDir的默认�??

		if (baseDir == null)
			baseDir = "/UserFiles/";
		String realBaseDir = getServletContext().getRealPath(baseDir);
		File baseFile = new File(realBaseDir);
		// 建立目录
		if (!baseFile.exists()) {
			baseFile.mkdir();
		}
		// 得到允许上传的Image类型,从web.xml�?

		allowedType = this.getInitParameter("AllowedExtensionsImage");
		unallowedFileType = this.getInitParameter("UnallowedExtensionsFile");
	}

	/**
	 * doGet方法处理(GetFolders, GetFoldersAndFiles, CreateFolder).
	 * 此servlet接收如下参数 <br>
	 * connector?Command=CommandName&Type=ResourceType&CurrentFolder=FolderPath
	 * 它最后返回xml
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/xml; charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();

		String commandStr = request.getParameter("Command");
		// 得到文件类型,Image,File,Flash,Media
		String typeStr = request.getParameter("Type");
		// 得到当前的目�?

		String currentFolderStr = request.getParameter("CurrentFolder");
		// 得到当前目录的真实路�?

		String currentPath = baseDir + typeStr + currentFolderStr;
		String currentDirPath = getServletContext().getRealPath(currentPath);
		// 创建当前路径
		File currentDir = new File(currentDirPath);
		if (!currentDir.exists()) {
			currentDir.mkdir();
		}
		// 创建返回的xml文件
		Document document = null;
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			document = builder.newDocument();
		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		}

		Node root = CreateCommonXml(document, commandStr, typeStr,
				currentFolderStr, request.getContextPath() + currentPath);
		// 得到用户选择的目�?

		if (commandStr.equals("GetFolders")) {
			getFolders(currentDir, root, document);
		}
		// 得到用户选择的目录的文件
		else if (commandStr.equals("GetFoldersAndFiles")) {
			getFolders(currentDir, root, document);
			getFiles(currentDir, root, document);
		}
		// 新建的目�?

		else if (commandStr.equals("CreateFolder")) {
			String newFolderStr = request.getParameter("NewFolderName");
			File newFolder = new File(currentDir, newFolderStr);
			String retValue = "110";
			// 只能输入英文字符数字或下划线
			if (!(Pattern.matches("\\w+", newFolderStr))) {
				retValue = "102";
			}
			// 目录已经存在
			else if (newFolder.exists()) {
				retValue = "101";
			}
			// 建立新目�?

			else {
				try {
					boolean dirCreated = newFolder.mkdir();
					if (dirCreated)
						retValue = "0";
					else
						retValue = "102";
				} catch (SecurityException sex) {
					retValue = "103";
				}

			}
			setCreateFolderResponse(retValue, root, document);
		}

		document.getDocumentElement().normalize();
		try {
			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer();

			DOMSource source = new DOMSource(document);

			StreamResult result = new StreamResult(out);
			transformer.transform(source, result);

			if (debug) {
				StreamResult dbgResult = new StreamResult(System.out);
				transformer.transform(source, dbgResult);
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		out.flush();
		out.close();
	}

	/**
	 * 处理文件上传 <br>
	 * 
	 * 此servlet接收如下参数: <br>
	 * connector?Command=FileUpload&Type=ResourceType&CurrentFolder=FolderPath
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html; charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();

		String commandStr = request.getParameter("Command");
		// 得到文件类型,Image,File,Flash,Media
		String typeStr = request.getParameter("Type");
		// 得到当前目录
		String currentFolderStr = request.getParameter("CurrentFolder");
		// 得到当前的真实路�?

		String currentPath = baseDir + typeStr + currentFolderStr;
		String currentDirPath = getServletContext().getRealPath(currentPath);

		String retVal = "0";
		String newName = "";

		if (!commandStr.equals("FileUpload"))
			retVal = "203";
		else {
			// 产生的上传对�?,并设置编�?

			DiskFileUpload upload = new DiskFileUpload();
			upload.setHeaderEncoding("UTF-8");
			try {
				List items = upload.parseRequest(request);

				Map fields = new HashMap();

				Iterator iter = items.iterator();
				while (iter.hasNext()) {
					FileItem item = (FileItem) iter.next();
					if (item.isFormField())
						fields.put(item.getFieldName(), item.getString());
					else
						fields.put(item.getFieldName(), item);
				}
				FileItem uplFile = (FileItem) fields.get("NewFile");
				String fileNameLong = uplFile.getName();
				fileNameLong = fileNameLong.replace('\\', '/');
				String[] pathParts = fileNameLong.split("/");
				String fileName = pathParts[pathParts.length - 1];

				String nameWithoutExt = getNameWithoutExtension(fileName);
				String ext = getExtension(fileName);
				File pathToSave = new File(currentDirPath, fileName);
				int counter = 1;
				// �?查允许上传的文件类型是否为Image,是则再检查文件类型在web.xml配置
				if ((this.checkImageType(allowedType, fileName))
						&& (typeStr.equals("Image"))) {
					retVal = "202";
				} else if ((this.checkFileType(unallowedFileType, fileName))
						&& (typeStr.equals("File"))) {
					retVal = "202";
				} else {
					while (pathToSave.exists()) {
						newName = nameWithoutExt + "(" + counter + ")" + "."
								+ ext;
						retVal = "201";
						pathToSave = new File(currentDirPath, newName);
						counter++;
					}
					uplFile.write(pathToSave);
				}
			} catch (Exception ex) {
				retVal = "203";
			}

		}

		out.println("<script type=\"text/javascript\">");
		out.println("window.parent.frames['frmUpload'].OnUploadCompleted("
				+ retVal + ",'" + newName + "');");
		out.println("</script>");
		out.flush();
		out.close();
	}

	private void setCreateFolderResponse(String retValue, Node root,
			Document doc) {
		Element myEl = doc.createElement("Error");
		myEl.setAttribute("number", retValue);
		root.appendChild(myEl);
	}

	private void getFolders(File dir, Node root, Document doc) {
		Element folders = doc.createElement("Folders");
		root.appendChild(folders);
		File[] fileList = dir.listFiles();
		for (int i = 0; i < fileList.length; ++i) {
			if (fileList[i].isDirectory()) {
				Element myEl = doc.createElement("Folder");
				myEl.setAttribute("name", fileList[i].getName());
				folders.appendChild(myEl);
			}
		}
	}

	private void getFiles(File dir, Node root, Document doc) {
		Element files = doc.createElement("Files");
		root.appendChild(files);
		File[] fileList = dir.listFiles();
		for (int i = 0; i < fileList.length; ++i) {
			if (fileList[i].isFile()) {
				Element myEl = doc.createElement("File");
				myEl.setAttribute("name", fileList[i].getName());
				myEl.setAttribute("size", "" + fileList[i].length() / 1024);
				files.appendChild(myEl);
			}
		}
	}

	private Node CreateCommonXml(Document doc, String commandStr,
			String typeStr, String currentPath, String currentUrl) {

		Element root = doc.createElement("Connector");
		doc.appendChild(root);
		root.setAttribute("command", commandStr);
		root.setAttribute("resourceType", typeStr);

		Element myEl = doc.createElement("CurrentFolder");
		myEl.setAttribute("path", currentPath);
		myEl.setAttribute("url", currentUrl);
		root.appendChild(myEl);

		return root;

	}

	/**
	 * 得到文件�?,没有扩展�?
	 * 
	 * 
	 * 
	 * @param fileName
	 * @return
	 */
	private static String getNameWithoutExtension(String fileName) {
		return fileName.substring(0, fileName.lastIndexOf("."));
	}

	/**
	 * 得到文件的扩展名
	 * 
	 * @param fileName
	 * @return
	 */
	private String getExtension(String fileName) {
		return fileName.substring(fileName.lastIndexOf(".") + 1);
	}

	/**
	 * �?查上传Image类型的的文件类型,根据在web.xml配置的信�?
	 * 
	 * 
	 * 
	 * @param type
	 * @param fileName
	 * @return
	 */
	private boolean checkImageType(String type, String fileName) {
		String[] ss = type.split("\\|");
		if (type.length() > 0) {
			for (int i = 0; i < ss.length; i++) {
				if (this.getExtension(fileName).equalsIgnoreCase(ss[i])) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 验证不允许上传的File类型的文�?
	 * 
	 * 
	 * @param type
	 * @param fileName
	 * @return
	 */
	private boolean checkFileType(String type, String fileName) {
		String[] ss = type.split("\\|");
		if (type.length() > 0) {
			for (int i = 0; i < ss.length; i++) {
				if (this.getExtension(fileName).equalsIgnoreCase(ss[i])) {
					return true;
				}
			}
		}
		return false;
	}

}
